/** @file main_window.cpp
    @brief Main window functions */
#include "main_window.h"

//! Blank picture path
static std::string g_blank_pic = "../res/blank.png";

MainWindow::MainWindow() {
	// Set scale to 1:1 by default
	m_scale = 1.0;
	// NULL all action pointers
	ma_fit_to_window = NULL;
	ma_normal_size = NULL;
	ma_zoom_in = NULL;
	ma_zoom_out = NULL;
	ma_show_pics = NULL;
	ma_delete = NULL;
	ma_exit = NULL;
	// NULL all menu pointers
	mm_file = NULL;
	mm_view = NULL;
	// NULL toolbar pointers
	mt_bar = NULL;

	// Set window title
	setWindowTitle( "QT Remote View" );

	// Enable scaling for the preview widget
	m_preview.setScaledContents( true );
	// Place preview into a scroll area widget
	m_scroll_area.setWidget( &m_preview );
	// Set scroll area widget as the central widget
	setCentralWidget( &m_scroll_area );

	// Prepare actions
	create_actions();
	// Prepare menus
	create_menus();
	// Prepare toolbars
	create_toolbars();
	// Create statusbar
	create_statusbar();

	// Resize the window
	resize( 700, 500 );

	// Show a background image
	show_image( g_blank_pic );
}

void MainWindow::create_actions() {
	ma_download = new QAction( "&Download", this );
	ma_download->setShortcut( tr( "Ctrl+D" ) );
	connect( ma_download, SIGNAL( triggered() ), this, SLOT( download() ) );
	if (style())
		ma_download->setIcon( QPixmap( "../res/download.png" ) );

	ma_delete = new QAction( "De&lete pics", this );
	ma_delete->setShortcut( tr( "Ctrl+L" ) );
	connect( ma_delete, SIGNAL( triggered() ), this, SLOT( delete_pics() ) );
	if (style())
		ma_delete->setIcon( QPixmap( "../res/delete.png" ) );

	ma_fit_to_window = new QAction( "&Fit to Window", this );
	ma_fit_to_window->setEnabled( false );
	ma_fit_to_window->setCheckable( true );
	ma_fit_to_window->setShortcut( tr( "Ctrl+F" ) );
	connect( ma_fit_to_window, SIGNAL( triggered() ), this, SLOT( fit_to_window() ) );
	if (style())
		ma_fit_to_window->setIcon( QPixmap( "../res/full.png" ) );

	ma_zoom_in = new QAction( "Zoom &In (25%)", this );
	ma_zoom_in->setShortcut( tr( "Ctrl++" ) );
	ma_zoom_in->setEnabled( false );
	connect( ma_zoom_in, SIGNAL( triggered() ), this, SLOT( zoom_in() ) );
	if (style())
		ma_zoom_in->setIcon( QPixmap( "../res/zoom_in.png" ) );

	ma_zoom_out = new QAction( "Zoom &Out (25%)", this );
	ma_zoom_out->setShortcut( tr( "Ctrl+-" ) );
	ma_zoom_out->setEnabled( false );
	connect( ma_zoom_out, SIGNAL( triggered() ), this, SLOT( zoom_out() ) );
	if (style())
		ma_zoom_out->setIcon( QPixmap( "../res/zoom_out.png" ) );

	ma_normal_size = new QAction( "&Normal Size", this );
	ma_normal_size->setShortcut( tr( "Ctrl+S" ) );
	ma_normal_size->setEnabled( false );
	connect( ma_normal_size, SIGNAL( triggered() ), this, SLOT( normal_size() ) );
	if (style())
		ma_normal_size->setIcon( QPixmap( "../res/normal.png" ) );

	ma_show_pics = new QAction( "&Show pics", this );
	ma_show_pics->setShortcut( tr( "Ctrl+W" ) );
	ma_show_pics->setEnabled( true );
	ma_show_pics->setCheckable( true );
	connect( ma_show_pics, SIGNAL( triggered() ), this, SLOT( show_pics() ) );
	if (style())
		ma_show_pics->setIcon( QPixmap( "../res/show.png" ) );

	ma_exit = new QAction( "E&xit", this );
	ma_exit->setShortcut( tr( "Ctrl+Q" ) );
	connect( ma_exit, SIGNAL( triggered() ), this, SLOT( close() ) );
	if (style())
		ma_exit->setIcon( style()->standardIcon( QStyle::SP_DialogCloseButton ) );
}

void MainWindow::update_actions() {
	if (ma_fit_to_window) {
		if (ma_zoom_in)
			ma_zoom_in->setEnabled( !ma_fit_to_window->isChecked() );
		if (ma_zoom_out)
			ma_zoom_out->setEnabled( !ma_fit_to_window->isChecked() );
		if (ma_normal_size)
			ma_normal_size->setEnabled( !ma_fit_to_window->isChecked() );
	}
}

void MainWindow::create_menus() {
	mm_file = new QMenu( tr( "&File" ), this );
	mm_file->addAction( ma_download );
	mm_file->addAction( ma_delete );
	mm_file->addSeparator();
	mm_file->addAction( ma_exit );

	mm_view = new QMenu( tr( "&View" ), this );
	mm_view->addAction( ma_zoom_in );
	mm_view->addAction( ma_zoom_out );
	mm_view->addAction( ma_normal_size );
	mm_view->addAction( ma_fit_to_window );
	mm_view->addSeparator();
	mm_view->addAction( ma_show_pics );

	if (menuBar()) {
		menuBar()->addMenu( mm_file );
		menuBar()->addMenu( mm_view );
	}
}

void MainWindow::create_toolbars() {
	if (!style())
		return;

	mt_bar = addToolBar( "Standard" );

	mt_bar->addAction( ma_download );
	mt_bar->addSeparator();
	mt_bar->addAction( ma_show_pics );
	mt_bar->addSeparator();
	mt_bar->addAction( ma_zoom_in );
	mt_bar->addAction( ma_zoom_out );
	mt_bar->addAction( ma_normal_size );
	mt_bar->addAction( ma_fit_to_window );
	mt_bar->addSeparator();
	mt_bar->addAction( ma_delete );
}

void MainWindow::create_statusbar() {
	if (!statusBar())
		return;

	m_status.setText( "Ready to go.." );

	statusBar()->addWidget( &m_status );
}

bool MainWindow::show_image( const std::string &s_path ) {
	m_preview.setPixmap( QPixmap( s_path.c_str() ) );

	if (ma_fit_to_window) {
		ma_fit_to_window->setEnabled( true );

		update_actions();

		if (!ma_fit_to_window->isChecked())
			m_preview.adjustSize();
	}

	return true;
}

void MainWindow::scale_image( double f_factor ) {
	if (m_preview.pixmap()) {
		m_scale *= f_factor;

		m_preview.resize( m_scale * m_preview.pixmap()->size() );

		adjust_scrollbar( m_scroll_area.horizontalScrollBar(), f_factor );
		adjust_scrollbar( m_scroll_area.verticalScrollBar(), f_factor );

		if (ma_zoom_in)
			ma_zoom_in->setEnabled( m_scale < 3.0 );
		if (ma_zoom_out)
			ma_zoom_out->setEnabled( m_scale > 0.333 );
	}
}

void MainWindow::zoom_in() {
	scale_image( 1.25 );
}

void MainWindow::zoom_out() {
	scale_image( 0.8 );
}

void MainWindow::normal_size() {
	m_preview.adjustSize();
	m_scale = 1.0;
}

void MainWindow::fit_to_window() {
	if (!ma_fit_to_window)
		return;

	bool fit = ma_fit_to_window->isChecked();

	m_scroll_area.setWidgetResizable( fit );

	if (!fit)
		normal_size();

	update_actions();
}

void MainWindow::adjust_scrollbar( QScrollBar *p_scrollbar, double f_factor ) {
	if (p_scrollbar)
		p_scrollbar->setValue( int ( f_factor * p_scrollbar->value() + ( ( f_factor - 1 ) * p_scrollbar->pageStep() / 2 ) ) );
}

void MainWindow::download() {
	std::string str;

	m_status.setText( "Downloading a picture.." );

    // Download an image
    m_image_path = m_download.fetch();

    // Update status
    str = "Picture " + m_image_path;
    m_status.setText( str.c_str() );

    // Show the image if needed
    if (ma_show_pics && ma_show_pics->isChecked())
	    show_image( m_image_path );
    else
	    show_image( g_blank_pic );
}

void MainWindow::delete_pics() {
	m_status.setText( "Deleting pictures.." );
#ifdef _WIN32
	system( "cd pics & del /Q * & cd .." );
#else
	system( "rm pics/*" );
#endif

	m_status.setText( "Pictures deleted.." );
}

void MainWindow::show_pics() {
	if (!ma_show_pics)
		return;

	bool show = ma_show_pics->isChecked();

	if (!show)
		show_image( g_blank_pic );
	else
		show_image( m_image_path );
}

